package org.ccay.excel.importer.service.impl;

import java.io.IOException;
import java.util.Map;
import java.util.ResourceBundle;

import javax.inject.Inject;
import javax.inject.Named;

import org.ccay.async.AsyncMessage;
import org.ccay.async.IMessageSender;
import org.ccay.async.task.ImportTaskVO;
import org.ccay.async.task.service.IImportTaskService;
import org.ccay.core.exception.ApplicationException;
import org.ccay.core.io.VFSFileObject;
import org.ccay.core.log.CcayLoggerFactory;
//import org.ccay.core.log.Audit;
import org.ccay.core.log.ILogger;
import org.ccay.core.request.IRequestContext;
import org.ccay.core.request.impl.RequestContext;
import org.ccay.core.util.JsonUtil;
import org.ccay.core.util.StringUtil;
import org.ccay.excel.exception.ExcelSystemException;
import org.ccay.excel.exception.ExcelValidationException;
import org.ccay.excel.importer.ExcelImportConstants;
import org.ccay.excel.importer.ExcelImportRequest;
import org.ccay.excel.importer.IExcelImportContext;
import org.ccay.excel.importer.internal.impl.ExcelImportProcessor;
import org.ccay.excel.importer.service.IExcelImportAssistant;
import org.ccay.excel.importer.service.IExcelImportSupport;
import org.ccay.excel.importer.service.impl.internal.ExcelImportContext;
import org.ccay.excel.importer.service.impl.internal.ExcelStreamReaderSax;
import org.ccay.excel.importer.service.impl.internal.InstantiatingNullHandler;
import org.ccay.excel.util.impl.ExcelUtil;

import ognl.OgnlRuntime;

/**
 * 导入助理的实现
 * @author chaowangbang
 * @since 2012-2-9
 */
@Named
public class ExcelImportAssitant implements IExcelImportAssistant {
    
	/**
	 * 任务服务
	 */
	@Inject
	private IImportTaskService taskService;
	
	/**
	 * 异步服务
	 */
	@Inject 
	private IMessageSender messageSender;
 
 
	@Inject
	private ResourceBundle resourceBundle;
	
	
	/** 日志记录器 **/
	private final ILogger logger = CcayLoggerFactory.getLogger(ExcelImportProcessor.class);
	/* (non-Javadoc)
	 * @see org.ccay.excel.importer.service.IExcelImportAssistant#submitImportTask(org.ccay.core.io.FileInfoVO, java.lang.String, java.util.Map)
	 */
//	@Audit(module="Import",operation="update",message="submitImportTask excelType={#excelType}")
	public ImportTaskVO submitImportTask(VFSFileObject fileInfo, String excelType,
			Map<String, String> context) throws ApplicationException {
		// 构造excel导入请求
		ExcelImportRequest importRequest = buildExcelImportRequest(excelType, fileInfo, context);
		
		// 创建一个导入任务
		ImportTaskVO importTask = createTask(fileInfo, excelType, context);
		importRequest.setTaskId(importTask.getTaskId());
		
		// 发送异步消息
		AsyncMessage message = new AsyncMessage("ExcelImport");
		message.setContent(importRequest);
		messageSender.send(message);	
		
		return importTask;
	}
	
	/** 构造Excel导入请求	
	 * @author chaowangbang
	 * @since Mar 16, 2012
	 * @param excelType
	 * @param fileInfo
	 * @param parameters
	 * @return
	 */
	private ExcelImportRequest buildExcelImportRequest(String excelType, VFSFileObject fileInfo, Map<String, String> parameters) {
		ExcelImportRequest importRequest = new ExcelImportRequest(excelType);
		importRequest.setDisplayFileName(fileInfo.getDisplayName());
		importRequest.setFilePath(fileInfo.getRelativePath());
		importRequest.setParameters(parameters);
		
		IRequestContext requestContext = RequestContext.getCurrent();
		importRequest.setUserLanguage(requestContext.getUserLanguage());
		
		return importRequest;
	}

	/** 
	 * 创建任务
	 * @param filePath
	 * @param fileName
	 * @param excelType
	 * @throws ApplicationException
	 */
	private ImportTaskVO createTask(VFSFileObject fileInfo, String excelType, Map<String, String> parameters) throws ApplicationException {
		ImportTaskVO excelImportTaskVO = new ImportTaskVO();
		String taskType = parameters.get("taskType");
		if(StringUtil.isNullOrEmpty(taskType)){
			taskType = StringUtil.firstUpperCase(StringUtil.subString4lastIndex(excelType, "."));
		}
		excelImportTaskVO.setTypeId(taskType);
		excelImportTaskVO.setTaskType(excelType);
		excelImportTaskVO.setDisplayFileName(fileInfo.getDisplayName());
		excelImportTaskVO.setFilePath(fileInfo.getRelativePath());
		excelImportTaskVO.setFileSize(fileInfo.getSize());
		excelImportTaskVO.setImportStatus(ExcelImportConstants.STATUS_WAITING); // 等待中
		
		//创建归档文件
		VFSFileObject archiveObject = fileInfo.copyToArchive();
		archiveObject.close();

		try {
			String taskParam = JsonUtil.getJsonString(parameters);
			excelImportTaskVO.setParameters(taskParam);
		} catch (IOException e) {
			logger.warn(e.getMessage());
		}
		
		taskService.createImportTask(excelImportTaskVO);
		
		return excelImportTaskVO;
	}
	
	/* (non-Javadoc)
	 * @see org.ccay.excel.importer.service.IExcelImportAssistant#getImportSupport(java.lang.String)
	 */
	public IExcelImportSupport getImportSupport(String excelType){
		try {
			return ExcelUtil.getImportSupport(excelType);
		} catch (ApplicationException e) {
			logger.error(e);
			throw new ExcelSystemException("ccay.excel.00060003","find importSupport error : excelType:"+excelType);
		}
	}

	public IExcelImportContext importExcel(VFSFileObject fileInfo,
			String excelType, Map<String, String> parameters)
			throws ApplicationException {
		/**
		 * 构造一个excel导入上下文
		 */
		ExcelImportContext context = null;
		// 构造excel导入请求
		ExcelImportRequest importRequest = buildExcelImportRequest(excelType, fileInfo, parameters);
		try {
			// 模块用户提供的excel导入支持
			IExcelImportSupport support = getImportSupport(importRequest.getExcelType());
			context = new ExcelImportContext(importRequest, support);
			context.setResourceBundle(resourceBundle);
			context.setMaxAllowedErrors(context.getMaxAllowedErrors());
			OgnlRuntime.setNullHandler(Object.class, new InstantiatingNullHandler());
			ExcelStreamReaderSax processor = new ExcelStreamReaderSax(context);
			processor.process();
			return context;
		} catch (ExcelValidationException e) {
			logger.error(e);
			return context;
		}
	}


}
